
package com.gxu.sjjg;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;


public class FindGrade extends JFrame {
//开始写hashmap
    public static void main(String[] args) throws IOException {
        new FindGrade();
    }
    public static String hash_byname[]=new String[127],hash_bysno[]=new String[127];//127=4*31+3，是满足4k+3的素数,p=113,是满足小于tablesize的最大素数
    public static int p=113;//p是表长
    public FindGrade() throws IOException {
        initComponents();
        add_to_hash();
    }
    private void add_to_hash(){//首先建立两个哈希表，表hash_byname[]是以姓名为键，表hash_bysno[]是以学号为键，
        try {
            String s;
            BufferedReader f = new BufferedReader(new FileReader("src/file/Grade.txt"));
            f.readLine();//先把第一行读完
            //同时为两个表添加数据
            while ((s = f.readLine()) != null) {
                String keyname = s.substring(0, 9).trim(), keysno = s.substring(10, 19).trim();//
                int name_len = keyname.length(), xuehao_len = keysno.length();//汉字字符值范围为19968-40869
                int keyvalue_name=0,keyvalue_sno=0,kk=1;//kk是权重
                //为姓名关键词表赋值
                for(int i=0;i<name_len;i++){
                    keyvalue_name+= (int)keyname.charAt(i)*kk;//用姓名的各个字符的unicode编码乘以权重，然后加起来作为散列值
                    kk*=2;
                }
                keyvalue_name=keyvalue_name%p;
                while(hash_byname[keyvalue_name]!=null){//处理冲突，如果产生冲突，则往后找空的地址
                    keyvalue_name++;
                    keyvalue_name=keyvalue_name%p;//将散列值映射到数组下标（即地址）
                }
                hash_byname[keyvalue_name]=s;
                //为学号关键词赋值
                keyvalue_sno=Integer.parseInt(keysno)%p;
                while (hash_bysno[keyvalue_sno]!=null){
                    keyvalue_sno++;
                    keyvalue_sno=keyvalue_sno%p;
                }
                hash_bysno[keyvalue_sno]=s;
            }
            f.close();
        }catch(Exception e2){
            e2.printStackTrace();
        }
    }

    //查询成绩
    private void button1(ActionEvent e) {
        boolean error=false,achieve = false;
        int n=tablemodel.getRowCount();//通过看表中是否有数据判断是否连续查询，若是，则先清空表格；
        for(int i=0;i<n;i++)
            tablemodel.removeRow(0);//特别注意，不能是removeRow(i),因为最后可能已经没有i行了
        String regex="\\d{1,9}",getname=textField1.getText(),xuehao=textField2.getText(),s;
        String match1="[\\u4e00-\\u9fa5]{1,6}";//汉字的unicode编码范围为\u4e00-\u9fa5,
        String data,dna,dsno,dchi,dmat,deng,dspo;//将添加进表格的各数据项,data存了所有数据。
        //学号最高十位
        //判断数据是否非法（姓名只能是1至六个汉字，是否同时为空，学号是否为数字，不超过9个字符
        if(!xuehao.matches(regex)&&!xuehao.equals("")||!getname.matches(match1) &&!getname.equals("")||xuehao.equals("")&&getname.equals(""))
            error=true;
        if(error){
            JOptionPane.showMessageDialog(null, "数据不合法！", "提示", JOptionPane.WARNING_MESSAGE);
        }
        else {
            try {
                if(!getname.equals("")&&!xuehao.equals("")){//如果学号和姓名都不为空，先通过学号定位数据，再通过学号判断输入信息是否有误
                    int keyvaluesno=Integer.parseInt(xuehao)%p;//将学号转化为散列值
                    while(hash_bysno[keyvaluesno]!=null){
                        data=hash_bysno[keyvaluesno];
                        if(data.substring(10,19).trim().equals(xuehao)&&data.substring(0,9).trim().equals(getname)){//输入的姓名与学号对应，表明找到该学生
                            achieve=true;
                            dna=getname;
                            dsno=xuehao;
                            dchi=data.substring(20,29).trim();
                            dmat=data.substring(30,39).trim();
                            deng=data.substring(40,49).trim();
                            dspo=data.substring(50,59).trim();
                            String[] data1={dna,dsno,dchi,dmat,deng,dspo,String.valueOf(Integer.parseInt(dchi)+Integer.parseInt(dmat)+Integer.parseInt(deng)+Integer.parseInt(dspo))};
                            tablemodel.addRow(data1);
                            break;
                        }
                        keyvaluesno=(keyvaluesno+1)%p;;
                    }

                }
                else if(!getname.equals("")){//只输入姓名
                    int keyvaluename=0,kk=1;
                    for(int i=0;i<getname.length();i++) {//计算键值
                        keyvaluename += (int) getname.charAt(i) * kk;
                        kk *= 2;
                    }
                    keyvaluename=keyvaluename%p;
                    while(hash_byname[keyvaluename]!=null){
                        data=hash_byname[keyvaluename];
                        if(data.substring(0,9).trim().equals(getname)){//找到该学生
                            achieve=true;
                            dna=getname;
                            dsno=data.substring(10,19).trim();
                            dchi=data.substring(20,29).trim();
                            dmat=data.substring(30,39).trim();
                            deng=data.substring(40,49).trim();
                            dspo=data.substring(50,59).trim();
                            String[] data1={dna,dsno,dchi,dmat,deng,dspo,String.valueOf(Integer.parseInt(dchi)+Integer.parseInt(dmat)+Integer.parseInt(deng)+Integer.parseInt(dspo))};
                            tablemodel.addRow(data1);

                            //break;
                            // 这里就不用break了，可能有重名的
                        }
                        keyvaluename=(keyvaluename+1)%p;
                    }
                }
                else{//只输入学号
                        int keyvaluesno=Integer.parseInt(xuehao)%p;
                        while(hash_bysno[keyvaluesno]!=null){
                            data=hash_bysno[keyvaluesno];
                            if(data.substring(10,19).trim().equals(xuehao)){//找到该学生
                                achieve=true;
                                dna=data.substring(0,9).trim();
                                dsno=xuehao;
                                dchi=data.substring(20,29).trim();
                                dmat=data.substring(30,39).trim();
                                deng=data.substring(40,49).trim();
                                dspo=data.substring(50,59).trim();
                                String[] data1={dna,dsno,dchi,dmat,deng,dspo,String.valueOf(Integer.parseInt(dchi)+Integer.parseInt(dmat)+Integer.parseInt(deng)+Integer.parseInt(dspo))};
                                tablemodel.addRow(data1);
                                break;
                            }
                            keyvaluesno=(keyvaluesno+1)%p;;
                        }
                }
                if(!achieve)//查找失败
                    JOptionPane.showMessageDialog(null, "没有该学生信息！", "提示", JOptionPane.WARNING_MESSAGE);
            } catch (Exception ee) {
                ee.printStackTrace();
            }
        }
    }

    private void ball(ActionEvent e) throws IOException {//显示所有学生信息
        int n=tablemodel.getRowCount();//判断是否连续查询，若是，则先清空表格；
        for(int i=0;i<n;i++)
            tablemodel.removeRow(0);//特别注意，不能是removeRow(i),因为最后可能已经没有i行了
        String s;
        BufferedReader fbr = new BufferedReader(new FileReader("src/file/Grade.txt"));
        fbr.readLine();//先把第一行读完
        while ((s = fbr.readLine()) != null) {
            String yuwen=s.substring(20, 29).trim(),math=s.substring(30, 39).trim(),english=s.substring(40, 49).trim(),sport=s.substring(50, 59).trim();
            String[] data={s.substring(0,  9).trim(),s.substring(10, 19).trim(),yuwen,math,english,sport,String.valueOf(Integer.parseInt(yuwen)+Integer.parseInt(math)+Integer.parseInt(english)+Integer.parseInt(sport))};
            tablemodel.addRow(data);
        }
        fbr.close();
    }
//界面设计
    private void initComponents() {
        // JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
        panel1 = new JPanel();
        label1 = new JLabel();
        textField1 = new JTextField();
        textField2 = new JTextField();
        label2 = new JLabel();
        scrollPane1 = new JScrollPane();
        table1 = new JTable(tablemodel);
        button1 = new JButton();
        button2 = new JButton();
        table1.setRowSorter(new TableRowSorter<>(tablemodel));
        //======== this ========
        setTitle("\u6210\u7ee9\u67e5\u8be2");
        setVisible(true);
        var contentPane = getContentPane();
        contentPane.setLayout(null);

        //======== panel1 ========
        {
            panel1.setLayout(null);

            //---- label1 ----
            label1.setText("\u59d3\u540d:");
            panel1.add(label1);
            label1.setBounds(30, 30, 30, label1.getPreferredSize().height);
            panel1.add(textField1);
            textField1.setBounds(60, 25, 100, 30);
            panel1.add(textField2);
            textField2.setBounds(235, 25, 100, 30);

            //---- label2 ----
            label2.setText("\u5b66\u53f7:");
            panel1.add(label2);
            label2.setBounds(205, 30, 30, 18);

            //======== scrollPane1 ========
            {
                scrollPane1.setViewportView(table1);
            }
            panel1.add(scrollPane1);
            scrollPane1.setBounds(15, 65, 405, 195);

            //---- button1 ----
            button1.setText("\u67e5\u8be2");
            button1.addActionListener(e -> button1(e));
            panel1.add(button1);
            button1.setBounds(new Rectangle(new Point(95, 275), button1.getPreferredSize()));

            //---- button2 ----
            button2.setText("\u663e\u793a\u6240\u6709\u5b66\u751f\u6210\u7ee9");
            button2.addActionListener(e -> {
                try {
                    ball(e);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            });
            panel1.add(button2);
            button2.setBounds(205, 275, 140, button2.getPreferredSize().height);

            {
                // compute preferred size
                Dimension preferredSize = new Dimension();
                for(int i = 0; i < panel1.getComponentCount(); i++) {
                    Rectangle bounds = panel1.getComponent(i).getBounds();
                    preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
                    preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
                }
                Insets insets = panel1.getInsets();
                preferredSize.width += insets.right;
                preferredSize.height += insets.bottom;
                panel1.setMinimumSize(preferredSize);
                panel1.setPreferredSize(preferredSize);
            }
        }
        contentPane.add(panel1);
        panel1.setBounds(0, 0, 435, 330);

        contentPane.setPreferredSize(new Dimension(435, 360));
        pack();
        setLocationRelativeTo(getOwner());
        // JFormDesigner - End of component initialization  //GEN-END:initComponents
    }

    public boolean isCellEditable (int row,int column){//表格不能编辑
        return false;
    }
    // JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables
    private JPanel panel1;
    private JLabel label1;
    private JTextField textField1;
    private JTextField textField2;
    public JLabel label2;
    private JScrollPane scrollPane1;
    public JTable table1;
    private JButton button1;
    private JButton button2;
    // JFormDesigner - End of variables declaration  //GEN-END:variables

    String[] columnname={"姓名","学号","语文","数学","英语","体育","总分"};
    String[][] tablevalues={};
    DefaultTableModel tablemodel=new DefaultTableModel(tablevalues,columnname);

}
